/*=========================================================================
| KCardDAV
|--------------------------------------------------------------------------
| (c) 2010  Kumaran Santhanam
|
| This project is released under the GNU General Public License.
| Please see the file COPYING for more details.
|--------------------------------------------------------------------------
| General job class.
 ========================================================================*/

/*=========================================================================
| INCLUDES
 ========================================================================*/

#ifndef KCARDDAV_JOB_H
#define KCARDDAV_JOB_H

#include "common.h"
#include <QtCore/QThread>

#include <neon/ne_session.h>
#include <neon/ne_request.h>

//forward declarations
namespace KABC { class ResourceCardDav; }
class QString;
class QUrl;
class QByteArray;

namespace KABC { namespace carddav {

/*=========================================================================
| CLASS
 ========================================================================*/

class Job : public QThread {
    Q_OBJECT
public:
    Job(const QUrl& url);
    virtual ~Job();

    void syncStart();

    /**
     * @return 0 if all OK, or a non-zero error code.
     */
    int error() const;

    /**
     * @return an error string (some additional information about the error, may be empty).
     * If all OK, an empty string is returned.
     */
    QString errorInfo() const;

    /**
     * This method must be called from the main UI thread.
     */
    void finish(ResourceCardDav* customer);

protected:
    virtual void run();

    void setError(int code, const QString& info);
    const QUrl& url() const;

private:
    virtual void processHeader(const char* name, const char* value);
    virtual ne_request* createRequest(ne_session* session) = 0;
    virtual bool requestAgain();
    virtual void requestFinished();
    virtual bool acceptResponse(ne_request *req, const ne_status *st);

    /**
     * This method is called when finished() method is called AND the job is not ended up with an error.
     * Should be implemented in subclasses to do actual resource altering.
     * No @p customer locking is necessary here, since this method must be called from the main UI thread.
     */
    virtual void jobFinished(ResourceCardDav* customer);

    /**
     * Response body callback.
     * After all the response body has been read, the callback will be called with a 'len' argument of
     * zero.
     */
    virtual void blockRead(const char *buf, size_t len) = 0;

    DECLARE_PIMPL(Job)
};

}} // namespaces

#endif

